from django.shortcuts import render, get_object_or_404, reverse
from django.http import HttpResponseRedirect
from django.views import generic
from django.db import transaction
from django.db.models import Q

from dal_select2_queryset_sequence.views import Select2QuerySetSequenceView
from queryset_sequence import QuerySetSequence
from dal import autocomplete

from .models import EquipmentList, AccessoriesModel, PowerSupplyModel, NetworkDeviceModel, SeismicEquipmentEntity
from .forms import EquipmentItemFormSet, PowerSuppliesItemFormSet, PowerSuppliesItemForm, NetworkDevicesItemFormSet, \
    NetworkDevicesItemForm, \
    EquipmentListForm

from seisnet.models import Station


class EquipmentAutocompleteView(Select2QuerySetSequenceView):
    def get_queryset(self):
        accessories = AccessoriesModel.objects.all()
        powersupplies = PowerSupplyModel.objects.all()
        networkdevices = NetworkDeviceModel.objects.all()

        qs = QuerySetSequence(accessories, powersupplies, networkdevices)

        if self.q:
            qs = qs.filter(Q(name__icontains=self.q) | Q(brand__icontains=self.q))

        qs = self.mixup_querysets(qs)

        return qs


class AccessoriesAutocompleteView(Select2QuerySetSequenceView):
    def get_queryset(self):
        qs = AccessoriesModel.objects.all()

        if self.q:
            qs = qs.filter(name__icontains=self.q)

        return qs


class PowerSupplieseAutocompleteView(Select2QuerySetSequenceView):
    def get_queryset(self):
        qs = PowerSupplyModel.objects.all()

        if self.q:
            qs = qs.filter(name__icontains=self.q)

        return qs


class NetworkdevicesAutocompleteView(Select2QuerySetSequenceView):
    def get_queryset(self):
        qs = NetworkDeviceModel.objects.all()

        if self.q:
            qs = qs.filter(name__icontains=self.q)

        return qs


class SeismologicalEquipmentEntityAutocomplete(autocomplete.Select2QuerySetSequenceView):
    def get_queryset(self):
        if self.kwargs.get('fk'):
            fk = self.kwargs.get('fk')
            belong_list = EquipmentList.objects.get(pk=fk)
            qs = SeismicEquipmentEntity.objects.filter(
                status='STOCK') | SeismicEquipmentEntity.objects.filter(belong_list=belong_list)
        else:
            qs = SeismicEquipmentEntity.objects.filter(status='STOCK')

        if self.q:
            qs = qs.filter(
                Q(sn__icontains=self.q) | Q(model__name__icontains=self.q) | Q(model__feature__icontains=self.q) | Q(
                    model__brand__icontains=self.q))

        return qs

    def get_result_value(self, result):
        return result.pk


class EquipmentListCreateView(generic.CreateView):
    model = EquipmentList
    form_class = EquipmentListForm

    fk_station_kwargs = 'station_id'

    def get_context_data(self, **kwargs):
        station = get_object_or_404(Station, pk=self.kwargs.get(self.fk_station_kwargs, None))

        if "equipmentlist" in station.__dict__.keys():
            return None

        context = super(EquipmentListCreateView, self).get_context_data(**kwargs)

        context['station'] = station
        if self.request.POST:
            context['equipmentitems'] = EquipmentItemFormSet(self.request.POST)
        else:
            context['equipmentitems'] = EquipmentItemFormSet()
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        equipmentitems = context['equipmentitems']
        with transaction.atomic():
            self.object = form.save(commit=False)
            self.object.station = context['station']
            self.object.save()

            if form.is_valid():
                seismic_equipment_entities = form.cleaned_data.get('seismic_equipment_entities')
                seismic_equipment_entities.update(belong_list=self.object, status='ONLINE')

            if equipmentitems.is_valid():
                equipmentitems.instance = self.object
                equipmentitems.save()

        return super(EquipmentListCreateView, self).form_valid(form)

    def render_to_response(self, context, **response_kwargs):
        station = get_object_or_404(Station, pk=self.kwargs.get(self.fk_station_kwargs, None))
        if context is None:
            return HttpResponseRedirect(reverse('equipment:equipmentlist_edit', kwargs={'station_id': station.pk}))

        return super(EquipmentListCreateView, self).render_to_response(context, **response_kwargs)


class EquipmentListUpdateView(generic.UpdateView):
    model = EquipmentList
    slug_field = 'station_id'
    slug_url_kwarg = 'station_id'
    form_class = EquipmentListForm
    fk_station_kwargs = 'station_id'
    template_name_suffix = '_form'

    def get_context_data(self, **kwargs):
        context = super(EquipmentListUpdateView, self).get_context_data(**kwargs)
        context['station'] = get_object_or_404(Station, pk=self.kwargs.get(self.fk_station_kwargs, None))
        # print(context['station'].pk)
        if self.request.POST:
            context['equipmentitems'] = EquipmentItemFormSet(self.request.POST, instance=self.object)
        else:
            context['equipmentitems'] = EquipmentItemFormSet(instance=self.object)
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        equipmentitems = context['equipmentitems']
        # seismic_equipment_entities = context['seismic_equipment_entities']
        station = context['station']
        old_seismic_equipment_entities = station.equipmentlist.seismic_equipment_entities

        with transaction.atomic():
            # self.object = form.save()
            self.object = form.save(commit=False)
            self.object.station = context['station']
            self.object.save()

            if form.is_valid():
                seismic_equipment_entities = form.cleaned_data.get('seismic_equipment_entities')
                old_seismic_equipment_entities.update(belong_list=None, status='UNDER_DETECTION')
                seismic_equipment_entities.update(belong_list=self.object, status='ONLINE')

            if equipmentitems.is_valid():
                equipmentitems.instance = self.object
                equipmentitems.save()

        return super(EquipmentListUpdateView, self).form_valid(form)
